package model.behaviors;

import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.List;
import model.Figure;
import model.Move;
import figures.Imgs;

/**
 * the king behavior
 */
public class King extends AbstractBehavior {

    /**
     * the constructor of this figure behavior
     * 
     * @param color
     *            the color to choose the right figure
     */
    public King( int color )
    {
	if ( color == Figure.WHITE )
	{
	    this.img = Imgs.KING_W;
	}
	else
	{
	    this.img = Imgs.KING_B;
	}
    }

    @Override
    public final void detectPossibleMoves( int fs, Graphics2D g, HashMap<String, Figure> figMap, Figure figure,
	    List<Move> movesList )
    {
	// empty list of valid fields
	this.validFields.clear();

	// calc x/y
	int x = figure.getX();
	int y = figure.getY();

	// up
	checkJumpFields( x, y - 1, figMap, figure );
	// up right
	checkJumpFields( x + 1, y - 1, figMap, figure );
	// right
	checkJumpFields( x + 1, y, figMap, figure );
	// down right
	checkJumpFields( x + 1, y + 1, figMap, figure );
	// down
	checkJumpFields( x, y + 1, figMap, figure );
	// down left
	checkJumpFields( x - 1, y + 1, figMap, figure );
	// left
	checkJumpFields( x - 1, y, figMap, figure );
	// up left
	checkJumpFields( x - 1, y - 1, figMap, figure );

	// end
	this.drawFields( fs, g );
    }

    /**
     * checks if the jump to a certain field is valid
     * 
     * @param x
     *            horizontal position
     * @param y
     *            vertical position
     * @param figMap
     *            reference to list of figures
     * @param figure
     *            reference to this figure object
     * @return indicates if field was valid
     */
    private boolean checkJumpFields( int x, int y, HashMap<String, Figure> figMap, Figure figure )
    {
	boolean ret = false;
	// still on the board?
	if ( x >= 0 && x <= 7 && y >= 0 && y <= 7 )
	{
	    // not the enemy king adjacent to that field?
	    if ( !isThatTheEnemyKing( x, y - 1, figMap, figure ) && !isThatTheEnemyKing( x + 1, y - 1, figMap, figure )
		    && !isThatTheEnemyKing( x + 1, y, figMap, figure )
		    && !isThatTheEnemyKing( x + 1, y + 1, figMap, figure )
		    && !isThatTheEnemyKing( x, y + 1, figMap, figure )
		    && !isThatTheEnemyKing( x - 1, y + 1, figMap, figure )
		    && !isThatTheEnemyKing( x - 1, y, figMap, figure )
		    && !isThatTheEnemyKing( x - 1, y - 1, figMap, figure ) )
	    {
		// empty field?
		if ( figMap.get( convertXYToField( x, y ) ) == null )
		{
		    this.addToValidFields( x, y );
		    ret = true;
		}
		// .. or enemy figure?
		else if ( figMap.get( convertXYToField( x, y ) ).getColor() != figure.getColor() )
		{
		    this.addToValidFields( x, y );
		    ret = true;
		}
	    }
	}
	return ret;
    }

    /**
     * Checks if the given field position holds the enemy king.
     * 
     * @param x
     *            horizontal position
     * @param y
     *            vertical position
     * @param figMap
     *            reference to list of figures
     * @param figure
     *            reference to this figure object
     * @return indicates if field holds enemy king or not
     */
    private boolean isThatTheEnemyKing( int x, int y, HashMap<String, Figure> figMap, Figure figure )
    {
	boolean ret = false;
	// TODO NullPointerException
	if ( x >= 0 && x <= 7 && y >= 0 && y <= 7 )
	{
	    if ( figMap.get( convertXYToField( x, y ) ) != null )
	    {
		if ( figMap.get( convertXYToField( x, y ) ).getBehav() instanceof King
			&& figMap.get( convertXYToField( x, y ) ).getColor() != figure.getColor() )
		{
		    ret = true;
		}
	    }
	}
	return ret;
    }
}
